<!--
 * @Author: actor
 * @Date: 2023-11-13 15:42:06
 * @email: 395593455@qq.com
 * @LastEditors: actor
 * @LastEditTime: 2023-12-21 10:29:06
 * @FilePath: \i-hos-app\shared\emr\src\views\editer\EditPage.vue
 * @Description: 电子病历编辑页面
-->
<template>
  <!-- minHeight: _emr_paper_set._h + 'mm', -->
  <div
    ref="emrPage"
    id="emr_page"
    :class="['emr_page', props.type == 'readOnly' ? 'readOnly' : '']"
    :style="{
      width: _emr_paper_set._w + 'mm',
      height: 'auto',
    }"
    @click="handFocusEvent"
    @keyup="
      (event: any) => {
        if (event.keyCode === 13) handFocusEvent
      }
    "
    @input="handFocusEvent"
  >
    <!-- 页眉 -->
    <div class="emr_page_head" :style="{ height: _emr_paper_set._t_e - 0.55 + 'mm' }">
      <span class="line" :style="{ top: _emr_paper_set._t_e - 5.45 + 'mm', left: _emr_paper_set._l_e - 5.45 + 'mm' }"></span>
      <span class="line" :style="{ top: _emr_paper_set._t_e - 5.45 + 'mm', right: _emr_paper_set._r_e - 5.45 + 'mm' }"></span>
      <span class="info" :style="{ top: _emr_paper_set._t_e + 'mm' }">页眉</span>
      <div id="emr_page_head">
        <div
          :class="['emr_page_editArea', props.isPrint ? 'print' : '']"
          :contenteditable="props.type != 'form'"
          :style="{
            width: _emr_paper_set._w - _emr_paper_set._r_e - _emr_paper_set._l_e + 'mm',
            height: _emr_paper_set._t_e - 0.55 + 'mm',
            marginRight: _emr_paper_set._r_e + 'mm',
            marginLeft: _emr_paper_set._l_e + 'mm',
            overflow: 'hidden',
          }"
          v-html="!!tmplJson ? tmplJson.head : ''"
        ></div>
      </div>
    </div>

    <!-- 正文 -->
    <div id="emr_page_body">
      <div
        :class="['emr_page_body emr_page_editArea', props.isPrint ? 'print' : '']"
        :contenteditable="props.type != 'form'"
        :style="{
          width: _emr_paper_set._w - _emr_paper_set._r_e - _emr_paper_set._l_e + 'mm',
          marginRight: _emr_paper_set._r_e + 'mm',
          marginLeft: _emr_paper_set._l_e + 'mm',
          minHeight: _emr_paper_set._h - _emr_paper_set._t_e - _emr_paper_set._b_e + 'mm',
          height: 'auto',
          overflow: 'hidden',
        }"
        v-html="!!tmplJson ? tmplJson.body : ''"
      ></div>
    </div>

    <!-- 页脚 -->
    <div class="emr_page_footer" :style="{ height: _emr_paper_set._b_e - 0.55 + 'mm' }">
      <span class="line" :style="{ bottom: _emr_paper_set._t_e - 5.45 + 'mm', left: _emr_paper_set._l_e - 5.45 + 'mm' }"></span>
      <span class="line" :style="{ bottom: _emr_paper_set._t_e - 5.45 + 'mm', right: _emr_paper_set._r_e - 5.45 + 'mm' }"></span>
      <span class="info">页脚</span>
      <div id="emr_page_footer" :style="{}">
        <div
          :contenteditable="props.type != 'form'"
          :class="['emr_page_editArea', props.isPrint ? 'print' : '']"
          :style="{
            width: _emr_paper_set._w - _emr_paper_set._r_e - _emr_paper_set._l_e + 'mm',
            marginRight: _emr_paper_set._r_e + 'mm',
            marginLeft: _emr_paper_set._l_e + 'mm',
            height: _emr_paper_set._b_e - 0.55 + 'mm',
            overflow: 'hidden',
          }"
          v-html="!!tmplJson ? tmplJson.footer : ''"
        ></div>
      </div>
    </div>

    <!-- 表格拖拽改变列宽列高的辅助线 -->
    <div class="table_resize_line"></div>

    <!-- 分页辅助线 -->
    <div class="emar_page_line" v-for="obj in pagingLine" :key="obj._t" :style="{ top: obj._t + 'px' }">
      <span>第{{ obj._i }}页, 共{{ obj._n }}页</span>
    </div>
    <!-- 编辑页面公共组件 -->
    <CommonList />
  </div>
</template>

<script setup lang="ts">
  import { Ref, ref, toRefs, watch } from 'vue'
  import { useResizeObserver, ResizeObserverEntry } from '@vueuse/core'
  // 接口约束
  import { ISetPaper, IPagingLine, ISetPaperState } from '../../interface/set'
  import { IPageConfigStore } from '../../interface/page'

  // 编辑页面公共组件
  import CommonList from '../../components/file/CommonList.vue'

  // 电子病历页面操作
  import { useHandleEmrPage } from '../../hooks/useHandleEmrPage'
  useHandleEmrPage()

  // 电子病历配置数据
  import { usePaperSetStore } from '../../store/paperSet'
  import { usePageConfigStore } from '../../store/pageConfig'

  // 公共需要处理的事件
  import { getRangeAt } from '../../utils/index'

  // 接收父组件值
  const props = defineProps({
    tmplJson: {
      type: String,
      default: '',
    },
    type: {
      type: String,
      default: '',
    },
    isPrint: {
      type: Boolean,
      default: false,
    },
  })

  // 解构 store的配置数据
  const paperSetStore: ISetPaperState = usePaperSetStore()
  const pageConfigStore: IPageConfigStore = usePageConfigStore()
  const { _emr_paper_set } = toRefs<any>(paperSetStore)

  // 初始化数据
  let emrPage: Ref<HTMLElement | null> = ref(null) // 电子病历纸张
  let pagingLine: Ref<IPagingLine[]> = ref([]) // 分页线数组
  let tmplJson: any = ref(null) // 模板数据

  // 设置纸张的分页以及分页辅助线
  const computedPageNumber = (_height: number): void => {
    // in(英寸)、cm(厘米)、mm(毫米)、pt(磅)、px(1/96英寸)
    // 单位换算关系为：1in = 2.54cm = 25.4mm = 72pt = 96px
    let _rate = 96 / 25.4 //  mm 转换率
    // let _emrPage_h: number = _emr_paper_set.value._h * _rate + 1 // 当前选择的纸张高度(加1是因为误差原因)
    let _emrPage_h: number = _emr_paper_set.value._h * _rate
    let _emr_h: number = _height // 当前选择纸张的内容所占的全部高度
    let _len: number = Math.ceil(_emr_h / _emrPage_h) // 计算纸张的分页张数
    // 清空重新计算一下纸张的分页页码
    pagingLine.value = []
    for (let i: number = 0; i < _len; i++) {
      pagingLine.value.push({
        _t: i + 1 == _len ? _emr_h : _emrPage_h * (i + 1),
        _i: i + 1,
        _n: _len,
      })
    }
  }

  // 监听纸张参数的变化， 重新计算一下纸张分页页码以及模板变化
  watch(
    (): any => [_emr_paper_set.value as ISetPaper, props.tmplJson],
    (): void => {
      // console.log("emrpage",props.tmplJson)
      if (!!props.tmplJson) {
        tmplJson.value = !!props.tmplJson ? JSON.parse(props.tmplJson) : ''
        if (Object.keys(tmplJson.value.json).length > 0) {
          // let _body = JSON.parse(JSON.stringify(tmplJson.value.body))
          // decodeURIComponent(_body)
          // console.log(_body, tmplJson.value.body)
          setTimeout(() => {
            let HEADER: any = tmplJson.value.json.HEADER,
              BODY: any = tmplJson.value.json.BODY,
              FOOTER: any = tmplJson.value.json.FOOTER

            // 设置电子病历模板页面相关配置json对应的元素内容
            if (Object.keys(HEADER).length > 0) {
              Object.keys(HEADER).forEach((val: string, key: string | number) => {
                if (HEADER[val] != undefined && document.getElementById(val) != null)
                  (document.getElementById(val) as Element).innerHTML = HEADER[val]
              })
            }
            if (Object.keys(BODY).length > 0) {
              Object.keys(BODY).forEach((val: string, key: string | number) => {
                if (BODY[val] != undefined && document.getElementById(val) != null)
                  (document.getElementById(val) as Element).innerHTML = BODY[val]
              })
            }
            if (Object.keys(FOOTER).length > 0) {
              Object.keys(FOOTER).forEach((val: string, key: string | number) => {
                if (FOOTER[val] != undefined && document.getElementById(val) != null)
                  (document.getElementById(val) as Element).innerHTML = FOOTER[val]
              })
            }
          })
        }
      } else {
        tmplJson.value = null
      }
      if (!!_emr_paper_set.value && emrPage.value != null) {
        setTimeout((): void => {
          computedPageNumber((emrPage.value as HTMLElement).offsetHeight as number)
        }, 100)
      }
    },
    { immediate: true, deep: true }
  )

  // 监听观察纸张的高度，设置分页辅助
  useResizeObserver(emrPage, (entries: readonly ResizeObserverEntry[]): void =>
    computedPageNumber(entries[0].contentRect.height as number)
  )

  // 触发电子病历页面获取光标的位置并保留光标的位置
  const handFocusEvent = (): void => {
    let rangeAt = getRangeAt()
    pageConfigStore.$patch?.((state: IPageConfigStore): void => {
      state.lastAangeAt = rangeAt
    })
  }
</script>

<style lang="scss" scoped>
  .emr_page {
    margin: 0 auto;
    background-color: #fff;
    position: relative;
    box-shadow: 0px 0px 5px #d3d3d3;
    font-size: 14px;
    // transform: scale(1, 1);
    &.readOnly {
      &::after {
        content: '只读模式，不可编辑';
        display: flex;
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        background: transparent;
        cursor: no-drop;
        align-items: center;
        font-size: 50px;
        color: #e8e8e8;
        justify-content: center;
      }
    }
  }
  .emr_page_editArea {
    font-family: 'Microsoft YaHei', Arial, sans-serif;
    font-size: 14px;
    padding: 1px;
  }
  .emr_page_head,
  .emr_page_footer {
    width: 100%;
    height: 1px;
    left: 0;
    border-bottom: 1px dashed #999;
    span.line {
      width: 5mm;
      height: 5mm;
      display: block;
      border-left: 1px solid #999;
      border-bottom: 1px solid #999;
      position: absolute;
      &:nth-of-type(1) {
        border-left: none;
        border-right: 1px solid #b37474;
      }
    }

    span.info {
      position: absolute;
      right: -30px;
      font-size: 13px;
      color: #999;
      margin-top: -15px;
    }
  }
  .emr_page_footer {
    border-bottom: none;
    border-top: 1px dashed #999;
    span.line {
      border-bottom: none;
      border-top: 1px solid #999;
    }
  }

  .emar_page_line {
    position: absolute;
    left: 0;
    width: 100%;
    height: 1px;
    border-top: 1px dashed #999;
    span {
      position: absolute;
      right: -80px;
      bottom: 5px;
      font-size: 13px;
      color: #999;
      top: -20px;
    }
  }
  .table_resize_line {
    position: fixed;
    border: 1px dashed #7460ee;
    box-shadow: 0px 0px 5px rgb(116 96 238 / 60%);
  }
  :deep(.resizeTable) {
    position: relative;
    &::after {
      content: '';
      display: block;
      position: absolute;
      width: 100%;
      height: 100%;
      background-color: rgb(255 255 255 / 40%);
      top: 0;
    }
  }
  :deep(.emr_page_editArea) {
    table {
      td {
        height: 20px;
        border: 1px solid #000;
        vertical-align: top;
      }
      td.selected {
        background-color: #d5cfff;
      }
    }
  }
  :deep(.filed_blank) {
    background-color: #dff;
    color: #5d5d5d;
    &:focus {
      outline: none;
      border: none;
    }
  }
  :deep(field) {
    // margin: 0 2px;
    font-size: 1em;
    line-height: 1em;
    padding: 0 2px;
    &.filed_blank {
      position: relative;
      display: inline-block;
      &::before,
      &::after {
        color: #409eff;
        display: inline-block;
        // position: absolute;
        // top: 0;
      }
      &::before {
        content: '{';
        // left: -3px;
      }
      &::after {
        content: '}';
        // right: -3px;
      }
    }
  }
  :deep(.selectBoxForm) {
    display: inline-block;
    outline: 1px dashed #409eff;
    > div {
      display: inline-block;
      cursor: pointer;
      padding-right: 5px;
      &:hover {
        background-color: #f5f5f5;
      }
      * {
        cursor: pointer;
      }
    }
  }
  .print {
    * {
      background-color: #fff !important;
      color: #000 !important;
    }
    :deep(.filed_blank) {
      background-color: #fff !important;
      color: #000 !important;
    }
  }
</style>
